

package modelo;

import proyecto2011.Archivo;
import java.util.Vector;

/**
 * Clase que representa un Esquema de un Base de Datos
 * @author Jaime Painefilu - Juan Demo 
 */
public class Esquema {
    String nombre;
    int nroTablas;
    int nroFunciones;
    int nroDominios;
    Vector listaTablas;
    Vector listaFunciones;
    Vector listaDominios;
    

    public Esquema(String nombre, int nroTablas) {
        this.nombre = nombre;
        this.nroTablas = nroTablas;
        this.nroFunciones = 0;
        this.nroDominios = 0;
        listaTablas = new Vector();
        listaFunciones = new Vector();
        listaDominios  =new Vector();
    }

    public String getNombre() {
        return nombre;
    }

    public void setNombre(String nombre) {
        this.nombre = nombre;
    }

    public int getNroTablas() {
        return nroTablas;
    }

    public void setNroTablas(int nroTablas) {
        this.nroTablas = nroTablas;
    }

    public int getNroFunciones() {
        return nroFunciones;
    }

    public void setNroFunciones(int nroFunciones) {
        this.nroFunciones = nroFunciones;
    }

    public Vector getListaTablas() {
        return listaTablas;
    }

    public void setListaTablas(Vector listaTablas) {
        this.listaTablas = listaTablas;
    }

    public void addTabla(Tabla tabla){
        this.listaTablas.addElement(tabla);
        this.nroTablas++;
    }

    public void showTablas(Archivo arch){
        Tabla tabla;
        for(int i=0; i<this.listaTablas.size(); i++){
            tabla = (Tabla) this.listaTablas.elementAt(i);
            tabla.showTabla(arch);
        }
    }
    
    public void showDominos(Archivo arch){
    	Dominio dominio;
        for(int i=0; i<this.listaDominios.size(); i++){
            dominio = (Dominio) this.listaDominios.elementAt(i);
            dominio.showDominio(arch);
        }
    }

    public int existTabla(String nombreTabla){
        Tabla tabla;
        int pos=-1;
        for(int i=0; i<this.listaTablas.size(); i++){
            tabla = (Tabla) this.listaTablas.elementAt(i);
            if(tabla.getNombre().equals(nombreTabla)) pos = i;
        }
        return pos;
    }

    public Vector getListaFunciones() {
        return listaFunciones;
    }

    public void setListaFunciones(Vector listaFunciones) {
        this.listaFunciones = listaFunciones;
    }

        
    public int getNroDominios() {
		return nroDominios;
    }

    public void setNroDominios(int nroDominios) {
            this.nroDominios = nroDominios;
    }

    public int existDominio(String nombreDom){
        Dominio dom;
        int pos=-1;
        for(int i=0; i<this.listaDominios.size(); i++){
            dom = (Dominio) this.listaDominios.elementAt(i);
            if(dom.getNombre().equals(nombreDom)) pos = i;
        }
        return pos;
    }

    public void addFuncion(Funcion func){
    this.listaFunciones.addElement(func);
    this.nroFunciones++;
    }    

    public Vector getListaDominios() {
		return listaDominios;
	}

    public void addDominio(Dominio dom){
		this.listaDominios.add(dom);
		this.nroDominios++;
    }

    public void showFunciones(Archivo arch){
        Funcion func;
        for(int i=0; i<this.listaFunciones.size(); i++){
            func = (Funcion) this.listaFunciones.elementAt(i);
            func.showFuncion(arch);
        }
    }
     public int existFuncion(String nombreFuncion){
        Funcion func;
        int pos=-1;
        for(int i=0; i<this.listaFunciones.size(); i++){
            func = (Funcion) this.listaFunciones.elementAt(i);
            if(func.getNombre().equals(nombreFuncion)) pos = i;
        }
        return pos;
    }

    public Archivo comparar(Esquema esq){
        Vector tablasExtras = new Vector();
        Vector funcionesExtras = new Vector();
        Vector dominiosExtras = new Vector();
        Archivo archivo = new Archivo("comparacion.txt");
        archivo.abrirEscritura();
        archivo.escribirLinea("\n####################################################################\n");
        archivo.escribirLinea("##                           COMPARACION DE BASES DE DATOS  ...                    ##\n");
        archivo.escribirLinea("####################################################################\n");
        if(!esq.nombre.equals(this.nombre))
            archivo.escribirLinea(("<< ADVERTENCIA! >> Diferencia en nombre de esquemas: "+this.nombre+"  "+esq.nombre)+"\n");
        else archivo.escribirLinea("  ** Nombre de esquemas iguales  "+this.nombre+"  "+esq.nombre+"\n");
        
        if(this.nroTablas == esq.nroTablas)
            archivo.escribirLinea("\n  ** Igual cantidad de tablas  "+this.nroTablas+"  "+esq.nroTablas+"\n");
        else archivo.escribirLinea("<< ADVERTENCIA! >> Diferencia en cantidad de tablas: "+this.nombre+"("+this.nroTablas+" Tablas)"+"  "+esq.nombre+"("+esq.nroTablas+" Tablas)\n");
        

    /*
     * INICIA COMPARACION DE TABLAS
     */
        archivo.escribirLinea("\n#######################################\n");
        archivo.escribirLinea("#######    ANALISIS DE TABLAS   #######\n");
        archivo.escribirLinea("#######################################\n");
        Tabla tabla;
        int nroTablasAct = this.nroTablas, nroTablasEsq = esq.nroTablas, nroTblcomun = this.nroTablas,posTActual;
        if(nroTablasAct > nroTablasEsq) nroTblcomun = nroTablasEsq;
        
        //compara las primeras n tablas comunes de los dos esquemas
        for(int i=0; i<nroTblcomun; i++){
            tabla = (Tabla) esq.listaTablas.elementAt(i);
            posTActual = existTabla(tabla.getNombre());            
            if(0 <= posTActual){
                tabla.compararTabla((Tabla)listaTablas.remove(posTActual), archivo);
            }else tablasExtras.addElement(tabla);
        }

        /*
         *  Si se da este caso es xq el esquema actual tenia mas tablas que el pasado como parametro,
         *  o tenian muy pocas tablas en común
         */
        if(!(this.listaTablas.isEmpty())){
        	archivo.escribirLinea("\n<< ADVERTENCIA! >>  Tablas Extras en  '"+this.getNombre()+"'\n\n");
            for(int i=0; i<this.listaTablas.size(); i++){
                tabla = (Tabla) this.listaTablas.elementAt(i);
                tabla.showTabla(archivo);
            }
        }
        /*
         * Si se da este caso es xq el esquema dado como parametro tenia tablas distintas al actual
         */
        if(!(tablasExtras.isEmpty())){
        	archivo.escribirLinea("\n<< ADVERTENCIA! >>  Tablas Extras en  '"+esq.getNombre()+"'\n\n");
            for(int i=0; i<tablasExtras.size(); i++){
                tabla = (Tabla) tablasExtras.elementAt(i);
                tabla.showTabla(archivo);
            }
            if(nroTablasAct < nroTablasEsq){                
                for(int i=nroTblcomun; i<esq.listaTablas.size(); i++){
                    tabla = (Tabla) esq.listaTablas.elementAt(i);
                    tabla.showTabla(archivo);
                }
            }
        }

         /*
         * INICIA COMPARACION DE FUNCIONES
         */
        int posActual;
        Funcion fun;
        archivo.escribirLinea("\n#######################################\n");
        archivo.escribirLinea("#######  ANALISIS DE FUNCIONES  #######\n");
        archivo.escribirLinea("#######################################\n");
        if(this.nroFunciones==esq.nroFunciones) 
            archivo.escribirLinea("**  Igual cantidad de funciones: " +this.nroFunciones+"\n");
        else{        	
            archivo.escribirLinea("<< ADVERTENCIA! >> Diferencia en cantidad de funciones: ");
            archivo.escribirLinea(this.nombre+"("+this.nroFunciones+" funciones)");
            archivo.escribirLinea("  "+esq.nombre+"("+esq.nroFunciones+" funciones)\n");
        }
        for(int j=0; j<esq.listaFunciones.size(); j++){
            fun = (Funcion) esq.listaFunciones.elementAt(j);
            posActual = this.existFuncion(fun.getNombre());            
            if(0 <= posActual){
                fun.compararFuncion((Funcion)this.listaFunciones.remove(posActual), archivo);
            }
            else funcionesExtras.addElement(fun);
        }
        if(!this.listaFunciones.isEmpty()){
            archivo.escribirLinea("\n<< ADVERTENCIA! >> Funciones Extras en (1er ESQUEMA): '"+this.getNombre()+"'\n");
            this.showFunciones(archivo);
        }
        if(!funcionesExtras.isEmpty()){
            archivo.escribirLinea("\n<< ADVERTENCIA! >> FUNCIONES EXTRA EN (2do ESQUEMA): '"+esq.getNombre()+"'\n");
            for(int i=0; i<funcionesExtras.size(); i++){
                fun = (Funcion) funcionesExtras.elementAt(i);
                fun.showFuncion(archivo);
            }
        }

         /*
         * INICIA COMPARACION DE DOMINIOS
         */
        int posAct;
        Dominio dom;
        archivo.escribirLinea("\n\n#######################################\n");
        archivo.escribirLinea("#######   ANALISIS DE DOMINIOS  #######\n");
        archivo.escribirLinea("#######################################\n");

        if(this.nroDominios==esq.nroDominios){
        	archivo.escribirLinea("**  Igual cantidad de Dominios: " +this.nroDominios+"\n");            
        }else{
            archivo.escribirLinea("<< ADVERTENCIA! >> Diferencia en cantidad de Dominios: ");
            archivo.escribirLinea(this.nombre+"("+this.nroDominios+" Dominios)");
            archivo.escribirLinea("  "+esq.nombre+"("+esq.nroDominios+" Dominios)\n");
        }
        for(int j=0; j<esq.listaDominios.size(); j++){
            dom = (Dominio) esq.listaDominios.elementAt(j);
            posActual = this.existDominio(dom.getNombre());
            if(0 <= posActual)
                dom.compararDominios((Dominio)this.listaDominios.remove(posActual),archivo);            
            else dominiosExtras.addElement(dom);
        }
        if(!this.listaDominios.isEmpty()){
        	archivo.escribirLinea("\n<< ADVERTENCIA! >> Dominios Extras en (1er ESQUEMA): '"+this.getNombre()+"'\n");
            this.showDominos(archivo);
        }
        if(!dominiosExtras.isEmpty()){
        	archivo.escribirLinea("\n<< ADVERTENCIA! >> Dominios Extras en (2do ESQUEMA): '"+esq.getNombre()+"'\n");
            for(int i=0; i<dominiosExtras.size(); i++){
                dom = (Dominio) dominiosExtras.elementAt(i);
                dom.showDominio(archivo);
            }
        }
        archivo.cerrar();
        return archivo;
    }
    
    public void showEsquema(){
         System.out.println("\n----------------------------------------");
         System.out.println("----------  Datos de esquema "+this.getNombre()+" ------");
         System.out.println("----------------------------------------\n");
    	 System.out.println("\n NUMERO DE TABLAS:  "+ this.nroTablas);
         //this.showTablas();
         System.out.print("\n NUMERO DE FUNCIONES: "+this.nroFunciones +"\n");
         //this.showFunciones();
         System.out.println();
         System.out.print("\n NUMERO DE DOMINIOS: "+ this.getNroDominios() +"\n");
         //this.showDominos(archivo);
    }
    

    
}
